home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
asm_reference
/
amigadisk_hardware.doc
< prev
next >
Wrap
Text File
|
1995-09-01
|
36KB
|
1,092 lines
This file is a more specialised look at hardware disc access. Requests for a
specialised DOC file covering this material have been fairly numerous now, so
I'm going to add this to the DOC file list. As per usual, this file will con-
tain material culled from the Amiga Hardware Reference Manual plus extra add-
itions of my own where deemed necessary (given that the Amiga manual writers
are all devotees of the terse school of writing, the additions are deemed to
be necessary on a regular basis!).
Contents:
Hardware Disc Access:Introduction
Hardware Disc Access:Hardware Organisation
Hardware Disc Access:CIA Timers For Delays
Hardware Disc Access:MFM And GCR Encoding
Hardware Disc Access:Basic I/O
Hardware Disc Access:Track Selection
Hardware Disc Access:Hardware Bugs
Hardware Disc Access:File Updates
Hardware Disc Access:Introduction
There have been a number of requests (particularly among ACC members)
for a DOC file on the subject of hardware disc access. Well, here it is. This
is partly a reworking of the Hardware Reference Manual (considered a strong
contender in some circles for the Plain English Society's gobbledegook award)
and various snippets of information that have come my way. As usual, I'll try
to make this file as simple to understand as possible given the subject mat-
ter.
Why hardware disc access? Well, games writers form one group of pro-
grammers who immediately come to mind when one thinks of people who require
this sort of information, as they are ALWAYS looking for sneaky tricks with
which they can bypass the OS and do their own thing. Whether it's custom boot
code or finding an alternative low-level disc data organisation to cram more
sound samples or graphics data into their creations, games programmers always
'hit the hardware' first and foremost.
Further down the list come system rpogrammers, who need hardware info
in order to provide those operating system routines that allow the remainder
of the programming community to write applications without having to reinvent
the wheel many times over to perform tasks such as loading and saving files.
Then there's the purely curious. ACC members usually fall into this
category, whether or not they fall into the previous two categories. This DOC
file should please this latter group too.
Programmers who have previously been satisfied with the DOS library
should take note of the following caveats:
1) ANY direct access to the hardware is GUARANTEED to
destroy Exec's multitasking integrity. If you want to
access hardware without compromising multitasking,
use the resources (disk.resource and misc.resource
etc, accessed in a like manner to devices);
2) Direct access to the disc hardware is complicated by
the use of two chip sets (the CIAs and the custom
chips);
3) Direct access to the disc hardware also requires a
knowledge of hardware-level disc formats (more on
this later). If you are not sure what MFM and GCR
formats are, then I suggest seeking out suitable
reference material before using the information in
this DOC file.
These warnings given, it is now time to move on. But before I do, note also
that this information applies to floppy disc controllers ONLY. Since I do not
have a hard disc, and certainly do not have a spare hard disc to experiment
with, I cannot give information on hard disc controllers (and in any case, it
is highly unlikely that anyone reading this DOC file is then going to go away
and write system software unless they're already employed by Commodore-Amiga,
and in that case they'll have far more information to hand than here!).
Hardware Disc Access:Hardware Organisation
Having stated that the disc hardware uses two different chip sets, I shall
now outline the disc hardware organisation.
The CIA chips (component number 8520) are used for drive selection &
disc sensing. The custom chips (specifically, Paula) are used for drive con-
trol (read/write mode), and to link areas of memory reserved by the program-
mer for disc access to the disc system. Note before I continue that as is the
case for ALL memory intended to be used in conjunction with the custom chips,
disc read/write buffers MUST be in CHIP RAM. This normally lies at the add-
resses given below:
$00000-$7FFFF : A500/A1000/A2000 with
original chip set
$00000-$FFFFF : A500/A1000/A2000/A1500
with Fatter Agnus chip
and the new A500P
$00000-$1FFFFF : A3000 with Super Fat
Agnus Chip (for rich
programmers only!)
However, this may NOT be true in the future! Commodore has already made four
changes to the chip set (the latest being the Enhanced Chip Set specifica-
tion as found on latest A3000s) and future changes may see future Amigas with
relocatable CHIP RAM pages, so you have been warned! For a method of reser-
ving CHIP RAM that works on ALL machines, use the Exec AllocMem() call via
exec.library (this HAS to work or else Commodore will face lawsuits!).
Having dealt with CHIP RAM, now to the registers of the disc hardware
system. First, the CIA registers. These lie at addresses $BFD000-$BFEFFF, but
not all of these addresses are used. Below is a table outlining the CIA regi-
ster set used by the disc hardware, including addresses, register names, and
functions. NOTE:many signals accepted by the CIA registers are ACTIVE LOW, in
other words, to turn the function ON requires a ZERO to be written into the
approriate register or register bit (as opposed to the normal signal logic,
called ACTIVE HIGH). In the table below, (L) denotes ACTIVE LOW, and (H) de-
notes ACTIVE HIGH.
Register Bit Function
-------- --- --------
CIAAPRA 5 DSKRDY signal (L).
($BFE001)
Drive will pull this signal low (clear
the bit) when the drive motor is known
to be rotating at full speed (see Note 1
below).
4 DSKTRACK0 signal (L).
Drive will pull this signal low (clear
the bit) when the disc drive read/write
heads are positioned over track zero (see
Note 2 below).
When this signal is active, software MUST
NOT ATTEMPT TO STEP THE HEADS OUTWARDS!
Modern add-on drives ignore the signal in
these circumstances, but older drives may
try to step out, resulting in a £35 repair
bill for a dead drive! YOU HAVE BEEN WARNED!
3 DSKPROT signal (L).
Disc write protected signal:
0 = Disc write protected
1 = Disc writeable
2 DSKCHANGE (L).
Disc changed signal. This bit becomes
zero when a disc is removed from the
drive (signalling a disc change). The
signal only becomes 1 again if a disc
is inserted AND a step pulse is re-
ceived (built-in safety feature, which
makes sure that a real disc is being
accessed, and not thin air).
CIABPRB 7 DSKMOTOR (L).
($BFD000)
Disc motor control signal. Implemented
in a non-standard fashion. Drives LATCH
the signal (i.e., keep their own private
copy of it) when selected. So, to force
a drive motor to be in a given state,
set or clear this bit, THEN send a signal
along one of the drive select lines. The
drive will "remember" the state of its
motor once the select signal is turned
off.
0 = Motor ON
1 = Motor OFF
CAUTION:after turning the motor ON,
software MUST wait for either 1/2 sec
(500 ms) or DSKRDY to go low. Other-
wise, the motor will NOT be at full
speed, and a write operation will
trash the disc!
6 DSKSEL3 (L).
Select drive 3 (DF3: if available on
the user's system).
0 = Select drive for operation
1 = Drive ignores other signals
5 DSKSEL2 (L).
Select drive 2 (DF2: if available on
the user's system).
0 = Select drive for operation
1 = Drive ignores other signals
4 DSKSEL1 (L).
Select drive 1 (DF1: if available on
the user's system).
0 = Select drive for operation
1 = Drive ignores other signals
3 DSKSEL0 (L).
Select drive 0 (DF0:), THE internal drive
on A500s (some A1000/2000 have two inter-
nal drives), and the one used for booting
WorkBench under KickStart 1.2/1.3.
0 = Select drive for operation
1 = Drive ignores other signals
2 DSKSIDE
Specify which disc read/write head to use.
All Amiga drives are double sided. Hence
there are two read-write heads. Use:
0 = Select UPPER surface disc head
1 = Select LOWER surface disc head
This value MUST be stable for at least
100 microseconds before writing, and
at least 1.3 MILLIseconds must elapse
before switching DSKSIDE.
1 DSKDIREC
Specify direction to seek the heads.
0 = Seek TOWARD CENTRE SPINDLE
1 = Seek TOWARD OUTER EDGE
This signal MUST be set up BEFORE
issuing a disc step signal. DO NOT
use a single write to the register
to perform both tasks! Use (for
example):
MOVE.B #$0A,CIABPRB
... short delay, e.g. NOP
MOVE.B #$09,CIABPRB
to step the heads outward on DF0:.
0 DSKSTEP (L).
Step the heads of the disc a distance
of one track. So, to step 5 tracks,
this signal needs to be sent 5 times.
The signal MUST be sent as:
Write 1 into bit
Write 0 into bit
Very short delay, e.g. a NOP
Write 1 into bit
As in:
MOVE.B #$08,CIABPRB
MOVE.B #$09,CIABPRB
NOP
MOVE.B #$08,CIABPRB
for EACH INDIVIDUAL step operation.
See notes 3,4.
CIABICR 4 DSKINDEX (L).
($BFDD00)
Disc index pulse. Can be used to gen-
erate a level 6 interrupt.
Notes on Above Table
1) DSKRDY valid ONLY when drive motor is ON. At other times,
configuration information may obscure the meaning of this
input.
2) Track zero is the OUTERMOST track of a disc. The usual
largest track is track 79, located nearest the centre of
the disc. Some drives (BUT NOT ALL!) are capable of
reading and writing up to track 83. DO NOT ASSUME that
software attempting such access will work on all machines!
3) Amiga drives are guaranteed to step to the next track within
3 milliseconds (3 ms). Some drives will perform much faster
than this, but NOT ALL. Using software delay loops (decre-
menting a counter) is NOT ACCEPTABLE (and not portable to
machines using 68020/68030 processors with higher clock
speeds). A better method is to use the CIA timers to pro-
vide the delay. See later.
4) When reversing directions, a MINIMUM delay of 18 ms is
required from the last step pulse. Settle time for Amiga
drives is specified at 15 ms.
That covers the CIA portion of the disc hardware. Now I present a table of
registers, bits and functions, this time for the various custom chip regis-
ters used by the disc hardware system (located at $DFF000 onwards). Note:
many registers exist as pairs, one for reading, one for writing. Write-only
register are denoted by (W), read-only registers by (R).
Register Bits Function
-------- ---- --------
$DFF020 3-0 DSKPTH (W)
$DFF022 15-0 DSKPTL (W)
Disc data pointer registers
Contains a pointer to the area of CHIP RAM
used for data transfer. Store the address
in these two registers. A single MOVE.L
can be used for this.
$DFF024 DSKLEN (W)
Disc data length & access register
15 DMAEN
Secondary disc DMA enable. Disc access
using a DMA channel CANNOT take place if
this bit is zero!
14 WRITE
0 = Read access
1 = Write access
13-0 LENGTH
These bits contain the number of WORDS to
transfer.
$DFF01A DSKBYTR (R)
Disc data byte & status read
15 DSKBYT
Set to 1 by disc system when bits 0-7
of this register contain a valid byte
of data. When this register is read by
the 68000 or DMA, this bit is cleared
for the next data byte status.
14 DMAON
Indicates when DMA is ACTUALLY ON. Is
only set to 1 when ALL DMA enable bits
pertinent to the disc system are set!
13 DISKWRITE
Reflects the state of the WRITE bit in
DSKLEN above.
12 WORDEQUAL
Indicates that the DSKSYNC register
equals the disc input stream. This
bit is only true while the input
stream matches the sync register,
which can be for as little as 2
microseconds! See below for DSKSYNC.
11-8 Currently unused. DO NOT RELY ON READ
VALUE.
7-0 DATA
Value of disc data byte that has been
read.
$DFF07E DSKSYNC (W)
Disc synchronisation value register
15-0 Disc synchronisation value. Normally
set to the magic MFM sync mark value
of $4489 by AmigaDOS. Hardware pro-
grammers can experiment with other
values (CAUTION!).
$DFF010 ADKCONR (R)
$DFF09E ADKCON (W)
Audio and Disc Control Register
Use in the following manner:
MOVE.W ADKCONR,D0 for READING
MOVE.W D0,ADKCON for WRITING
15 SET/CLR
Best illustrated by an example. If
the word $8001 is written to a regi-
ster with a SET/CLR bit, then bit 0
will be SET, and all other bits left
untouched. If the word $0001 is writ-
ten, then bit 0 will be CLEARED, and
all other bits left untouched. This
allows the programmer to affect ONLY
those bits required for the given
operation. Also, see typed_hardware.doc
for more info.
14 PRECOMP1
13 PRECOMP0
Precompensation value. Values are:
00 : No precompensation
01 : 140 ns precompensation
10 : 280 ns precompensation
11 : 560 ns precompensation
12 MFMPREC
0 = GCR precompensation (allows
Amiga drives to read Apple
Macintosh discs with certain
programming tricks)
1 = MFM (Normal AmigaDOS setting,
also allows Atari ST/IBM PC
discs to be read)
10 WORDSYNC
Set to 1 to allow synchronising and
starting of DMA on disc read of a word.
DSKSYCN contains the synchronisation
word. VERY USEFUL.
9 MSBSYNC
Set to 1 to enable synchronisation on
most significant bit of input (used for
GCR setting)
8 FAST
Value of 1 selects 2 microseconds per
bit cell (MFM). Data must be valid raw
MFM data. Value of 0 selects 4 micro-
seconds per bit cell (GCR).
This covers the register organisation of the disc hardware. Before covering
how to use the registers for disc access, it is time to cover MFM encoding &
related topics.
Hardware Disc Access:CIA Timers For Delays
The CIA chips contain on-board timer hardware, that allows the programmer to
implement precisely timed delay loops that can migrate happily across differ-
ent versions of the Amiga. This facility will be vital in managing the disc
hardware, so I shall now describe the usage of the CIA timers to generate a
fixed-period delay loop.
Now, the CIA timers are often chosen to implement delay loops that
are relatively independent of the remaining Amiga hardware. However, accord-
ing to the Concise Hardware Reference Manual, the timing signals for NTSC and
PAL Amigas differs slightly. The timing signals are:
NTSC : 715.909 KHz
PAL : 715.379 KHz
However, these timing signals remain constant across different Amiga specifi-
cations, from base A500 all the way to A3000 with 68040 accelerator board. As
a means of creating processor-independent delay loops, the CIAs are the prime
choice.
The best timer to use under most circumstances is the CIA-B Timer B,
and this timer can be found at $BFD600/$BFD700. It is a 16-bit timer, and to
use it requires setting control bits in the CIA control registers. But first
let's see the sequence of events in action:
MOVE.W #TIMEVAL,D0 ;Timer value
MOVE.B D0,CIABTBLO ;set low byte
LSL.W #8,D0
MOVE.B D0,CIABTBHI ;set high byte
This sequence sets the CIA-B Timer B write only latches. These are registers
that hold the timing value until the control register forces this value to be
loaded into the actual timer counters and counting to begin. Having set the
timer latches, it is time to start the timer. An instruction that can be used
is:
MOVE.B #%00011001,CIABCRB
If one refers to the Concise Hardware Reference Manual, and examines the bit
allocations of CIABCRB, the effect of the above instruction is:
1) Alarm bit (bit 7):don't care about it, so set
it to 0.
2) Inmode bits (Bits 6,5):Want timer to count the
incoming clock signal pulses, so set these bits
to 00.
3) Load bit (bit 4):Force timer to load the latch
values into the timer, and then count down to
zero, so set this bit to 1.
4) Runmode bit (bit 3):Set to 1 for one-shot mode
(since we only want a single delay).
5) Outmode bit (bit 2):Set to 0 to receive a pulse
on the line being sensed.
6) PBON bit (bit 1):Set to 0 (leave PB7 line alone
as it's needed elsewhere!).
7) Start bit (bit 0):Set to 1 to start the timer
counting down.
OK, now we've set off our timer. Now we need to be able to sense when it has
reaced the timeout condition (i.e., time is up). Well, the best way is to set
up the interrupt control register (CIABICR) to allow the CIA to generate an
interrupt upon a timeout. To allow Timer B to generate an interrupt within
the CIA itself, use:
MOVE.B #%10000010,CIABICR
or similar. This writes the control bits into the CIA's interrupt latch, and
allows Timer B to create an interrupt within the CIA.
Now, reading the same register address will read the CIA-B interrupt
input bits, and if Bit 1 is set, then the timer has timed out. Of course, as
CIA-B will generate a level 6 interrupt (IPL6 on the 68000), it is possible
to write a level 6 interrupt handler to check for this, but it is also poss-
ible to read the register directly (especially if the level 6 interrupt vec-
tor is disabled or redirected by the programmer for other reasons).
Timer A on the CIA-B can also be used (as it is not in use for any
operating system purposes) but if the operating system has been killed off by
the programmer, ALL of the timers are free. The above code applies mainly if
at least some facets of the operating system are being kept alive (for true
friendliness within the multitasking environment, use the CIA Resource, and
the Exec OpenResource() call).
Also, the programmer can choose to test the bits of the CIA interrupt
register directly or write an interrupt handler to do it (INT2 if using the
CIA-A timers, INT6 if using CIA-B). Don't forget to enable the required in-
terrupt in the 4703 interrupt controller (custom chip-write to INTENA, at ad-
dress $DFF09A to control the required interrupts), and to change the value of
the 68000 status register if required by your code. This requires access to
supervisor mode, which can be done in two ways. First, there is an Exec call
that will run a piece of code in supervisor mode:
MOVE.L ExecBase,A6
JSR Superstate(A6)
MOVE.L D0,Old_SSTk ;keep this value!
and allow recovery of user mode via:
MOVE.L Old_SSTk,D0
MOVE.L ExecBase,A6
JSR UserState(A6)
or alternatively, if you're killing off the operating system, try this rather
naughty piece of code:
LEA MyTrap0(PC),A0
MOVE.L A0,$80 ;addr of TRAP #0 vector
TRAP #0
... ;from here on, MOVE SR is
;allowed as you are in
;supervisor mode!
...
MyTrap0 MOVE.W (SP)+,D0 ;get status reg
BSET #13,D0 ;set supervisor mode
MOVE.W D0,-(SP) ;put back
RTE ;return in supervisor mode!
This is a very naughty piece of code (which destroys multitasking integrity)
of the sort that a games coder might like to use when returning to the oper-
ating system is not called for.
Now that we can implement CIA timer delay loops (needed later on), it
is time to look at MFM and GCR data encoding.
Hardware Disc Access:MFM And GCR Encoding
Those who haven't encountered direct writing to disc before may be surprised
to find that the actual bit patterns written to the disc differ from the bit
patterns of the data that the programmer writes to disc when using AmigaDOS
routines. Well, all is to be revealed.
The fundamental problem of writing data to a disc is detecting the
difference between a zero bit and a one bit. The next problem is detecting
the difference between individual bits, be they ones or zeros. Since the disc
read/write head uses magnetic fields for its operations, there are only two
possibilities:magnetic field on and magnetic field off. Allocating each of
these signals to a zero and one bit respectively would render detection of an
individual bit impossible.
To solve this problem, a scheme called frequency modulation was de-
vised, whereby CHANGES in the magnetic field value written to the disc were
used to signal the start of a bit, and the TYPE of change encountered used
to determine which type of bit was written during the original write opera-
tion. This scheme works for low-volume data storage, but when the density of
the data exceeds a certain value, the frequency of read/write errors builds
up to an unacceptable value. For the technically minded, the problem is that
high-speed flux changes take time to generate the respective electronic sig-
nal change, a time known as the half zero bit length, and the minimum value
of this is the main determinant of the maximum density of data storable on a
disc. Also, there is a delay during initiation of read/write operations, this
value being the precompensation value (although Amiga disc drives are capable
of handling read/write operations with zero precompensation). Generally, the
faster the read/write operation, the more precompensation needed.
Overcoming the problem of large precompensation values for densely
packed data on a disc led to the formation of Modified Frequency Modulated
encoding (MFM). This encoding scheme expands the actual data to twice its
original size, but in doing so generates raw data to write to the disc that
is efficient enough to allow 880K of user data to be stored on a 3.5 inch
disc.
So, what is MFM? The exact relationship is:
User Data Bit MFM Bits
------------- --------
1 01
0 10 if following a 0 data bit
0 00 if following a 1 data bit
Now according to the Amiga Hardware Reference Manual, it is possible to use
the blitter to encode and decode the MFM data. Well, for the record, I have
not tried this, so those willing to experiment might like to disassemble the
trackdisk.device and see if Commodore have written blitter MFM routines (and
if they haven't, why mention this?). Really clever programmers reading this
can write their own.
GCR encoding is an entirely different matter. Sad to say, Commodore-
Amiga do NOT give any in-depth information on this subject, other than to say
that a translation table (called a nibbliser table) is used to prevent too
many consecutive 1 or 0 bits occuring in the data stream. Users who want this
information should obtain a comprehensive reference work covering hardware-
level disc formats and floppy disc hardware in general. Anyone familiar with
Apple II (there's nostalgia for you!) disc drives and their hardware-level
format, or the Apple Macintosh disc format, please get in touch so that I can
provide information on GCR encoding for Amiga users!
As I was perusing the subject, a piece of code that performed MFM en-
coding and decoding without the need for the trackdisk device appeared on ACC
disc 18, so I decided to have a further look. The code turned out to be quite
interesting (as it had no comments explaining it-thanks Mark Flemans for an
example of the minimalist approach to documentation!), but apparently works.
Hardware Disc Access:Basic I/O
Now is the time to start using the registers and performing some actual disc
operations. The following code is all my own, to be considered freeware and
rippable/editable to the reader's preferences/sexual leanings etc.
First, disc access via the DMA channels. This is the usual method, &
has the advantage of allowing the 68000 to get on with other processing while
a disc is being read. Now users with one disc drive will not normally need to
consider the drive select signals, but I shall include the drive select code
so that the code can be used by users with more than one drive. The sequence
of operations looks like this in assembler:
MOVE.B #$78,CIABPRB ;switch ON motor, no drive select
MOVE.B #$F0,CIABPRB ;select drive 0
bwait1 BTST #5,CIAAPRA ;drive ready? (Busy wait-sigh)
BNE.S bwait1 ;wait until so
LEA $DFF000,A5 ;point to custom chips
MOVE.L #BUFFER,DSKPTH(A5) ;point to our buffer
* The two statement sets below are commented out. Remove the comment
* characters for the operation wanted.
* MOVE.W #$4000,DSKLEN(A5) ;turn off secondary disc DMA
* MOVE.W #$8000,D0 ;secondary DMA on, READ DISC
* ADD.W #DATASIZE,D0 ;no of WORDS to READ
* MOVE.W D0,DSKLEN(A5) ;need to write TWICE to
* MOVE.W D0,DSKLEN(A5) ;start the operation!
* MOVE.W #$4000,DSKLEN(A5) ;turn off secondary disc DMA
* MOVE.W #$C000,D0 ;secondary DMA on, WRITE DISC
* ADD.W #DATASIZE,D0 ;no of WORDS to WRITE
* MOVE.W D0,DSKLEN(A5) ;need to write TWICE to
* MOVE.W D0,DSKLEN(A5) ;start the operation!
... here wait for DMA to complete
MOVE.W #$4000,DSKLEN(A5) ;turn off disc DMA again
MOVE.B #$F8,CIABPRB ;turn motor OFF
MOVE.B #$F0,CIABPRB ;select drive 0
Ok, some notes about the above code. First, the motor is switched on, with
no drive select signals sent. Because the signals are ACTIVE LOW, the bits
to turn OFF a function are SET. The same applies to the drive select signal
immediately following.
Now anyone who has read my previous DOC files will know that I HATE
busy waits, such as the one that I've sadly included here. Well, this code is
intended to be simple to understand, so I'll break the golden rule and use a
busy wait to wait for the drive to be ready. This just waits for the DSKRDY
bit to go low. Of course, an alternative is to use the disk index pulse bit
to trigger a level 6 interrupt, and then read DSKRDY within the interrupt,
while your code does something more useful than twiddle its thumbs.
Now, point A5 at the custom chips, to make life easier (especially if
you use the hardware.i ACC include file), then point the DSKPTH/L registers
at the buffer of your choice.
Here, we decide whether to read or write to disc. Both code sections
are included above. Just remove the comment markers from the one required, &
delete the other.
Note that in order to set off a DMA disc operation, the DSKLEN regi-
ster must be written to TWICE. This is intended to prevent accidental writes
to a disc (which are of course always to be avoided!), and ensure that when
a disc operation is requested, the hardware receives a genuine request. The
above code does this.
Of course, it is possible to read or write the 'hard' way, using the
68000 to keep track of things, but the above is more efficient (barring the
busy wait).
Now, some restrictions. First, the above should be used to read or
write an entire track at a time. It is possible to modify it to read in one
sector at a time, but the above is not intended to be an advanced routine.
Sector-level disc I/O requires using the DSKBYTR and DSKSYNC registers, and
also probably requires handling via interrupts not only for maximum effic-
iency, but for maximum data integrity too. When using the above code for a
track read or write, the size of the buffer should be:
(512 * 11) * 2 + 2 = 11266 bytes
Size of 1 track MFM
Overhead
The reason for the size given is 1) a single sector is 512 bytes of user data
on a standard AmigaDOS disc; 2) there are 11 sectors per track; 3) all data
in MFM format is expanded to twice the uncoded size; 4) an extra word is to
be reserved to take account of a hardware bug (see below) that Commodore just
happen to have mentioned in the Amiga Hardware Reference Manual.
Now, there remains another task to be performed before reading data
from a disc. That is to make sure that the data coming off the disc is syn-
chronised to the actual data layout. The programmer wants to be sure that a
data stream coming in actually STARTS at the first word of the first sector
of the track being read. How is this done?
Well, for an AmigaDOS disc, load DSKSYNC with the magic value $4489.
This is a value called a 'sync mark'. This value is chosen so that there is
no way possible that any data on the disc encodes to this value. There are a
number of such values, but AmigaDOS uses $4489. Normal user data will never
encode to this number using MFM encoding as given above, and so the disc sys-
tem can use this value to mark the start of the track.
Having loaded DSKSYNC with the sync mark value, enable the WORDSYNC
bit in ADKCON prior to reading or writing. Then, data transfer will NOT be
performed until the sync mark is found, at which point the following word of
data on the disc will be the start point for data transfer. Use:
MOVE.W #$4489,DSKSYNC(A5)
where A5 points to the start of the custom chip registers ($DFF000). Then set
WORDSYNC in ADKCON:
MOVE.W #$9500,ADKCON(A5)
which sets the WORDSYNC, MFMPREC and FAST bits. Do this BEFORE the main code
for reading or writing discs above.
Hardware Disc Access:Track Selection
This is the final basic function to be performed. Track selection is a mite
complicated, because the drives do not signal directly (except for track 0)
when the heads are aligned over a given track. So, to perform this function,
the programmer MUST first seek to track 0 (at which point the DSKTRACK0 bit
of CIAAPRA will become zero. This requires first that the drive be selected,
then the motor turned on, then DSKDIREC set to 1 to force a seek to the outer
edge of the disc (where track 0 lies). Then, send a step pulse to DSKSTEP as
outlined above until DSKTRACK0 goes low. Then, SAVE this track number in a
variable set up within the program for this purpose. From this point on, to
find a given track requires a seek in the given direction, incrementing the
variable each time a step inwards is performed, and decrementing the varia-
ble when a step outwards is performed. Locating a specified track then requ-
ires a compare with the desired track number. For example, after selecting a
drive and turning on the motor, code such as the following may be used:
FindTRK0 btst #4,CIAAPRA ;hit track 0?
beq.s FoundTRK0 ;skip if so
move.b #%11110010,CIABPRB ;seek to outer, DF0:
... ;here set up a delay using a CIA timer
... ;for 18 milliseconds
move.b #%11110001,CIABPRB ;set DSKSTEP high
move.b #%11110000,CIABPRB ;then low
move.b #%11110001,CIABPRB ;then high again
... ;here set up 3 ms delay using
... ;a CIA timer
bra.s FindTRK0 ;and check if hit track 0
FoundTRK0 clr.w TrackNumber ;absolute variable (sigh)
... ;from here, can seek anywhere!
Having used this, code to seek in a given direction can use a second varia-
ble (call it TrackWanted). A CMP between the two will establish the seek di-
rection. Alternatively, use:
move.w TrackNumber,d0
move.w TrackWanted,d1
sub.w d0,d1 ;check seek direction
beq.s Done ;already there!
bpl.s Seek_Inward
neg.w d1
move.b #%11110110,CIABPRB ;set DSKDIREC outwards
... ;here CIA timer delay, 18 ms
Seek_Out move.b #%11110001,CIABPRB ;set DSKSTEP high
move.b #%11110000,CIABPRB ;then low
move.b #%11110001,CIABPRB ;then high again
subq.w #1,TrackNumber ;update track count
cmp.w TrackWanted,TrackNumber ;found req'd track?
beq.s Seek_Done ;got it!
subq.w #1,d1
bne.s Seek_out
...
Seek_Inward move.b #%11110100,CIABPRB ;set DSKDIREC inwards
... ;here CIA timer delay, 18 ms
Seek_In move.b #%11110001,CIABPRB ;set DSKSTEP high
move.b #%11110000,CIABPRB ;then low
move.b #%11110001,CIABPRB ;then high again
addq.w #1,TrackNumber ;update track count
cmp.w TrackWanted,TrackNumber ;found req'd track?
beq.s Seek_Done ;got it!
subq.w #1,d1
bne.s Seek_In
Seek_Done ...
This should cover most needs for hardware disc programmers. Those requiring a
routine to perform sector-level access, be warned that the facilities provi-
ded for sector-level access are limited. First, the DSKBYTR register must be
polled on a regular basis while the track is being scanned. Second, since the
disc system does NOT maintain sector counters in hardware, the programmer has
to provide variables for this purpose within the program. Unless there is a
shortage of available memory, and sector-level access is the ONLY option open
to the programmer, then reading an entire track in one go is a far superior
option.
Hardware Disc Access:Hardware Bugs
Now the bad news. The Amiga Hardware Reference Manual contains a short para-
graph (tucked away where it can't be seen too easily so as not to alarm the
first-time hardware programmer!) which mentions a disc hardware bug. Well, it
is really two bugs, one occurring during a read operation, and one occurring
during a write operation.
Firstly, during a read operation, the last word requested may not be
read. This doesn't always happen, but just in case it does, the buffer for a
hardware disc read should be one word longer than necessary. Also, for write
operations, the extra last word should match the first word of the buffer. I
forgot to reserve space for sync marks in the buffer information above (sorry
about that!), so make the first word the sync mark, then a track full of data
and finally a copy of the sync mark.
Hardware Disc Access:File Updates
For updated versions of this file, or any of the other files in this series
of DOC files, the contact addresses are:
Dave Edwards Mark Meany
232 Hale Road 12 Hinkler Road
WIDNES Thornhill
Cheshire SOUTHAMPTON
WA8 8QA Hants
The first of these is mine. Sending a blank formatted disc to me at the above
address, with a stamped, self-addressed jiffy bag for return postage (stand-
ard 1st class stamp sufficient) will get you the files of your choice, writ-
ten to your disc in uncompressed ASCII format. Sending a disc to Mark at the
above address (plus jiffy bag, stamp etc.) will get you one of the ACC club
discs which contain these files spread over a period (they were intended for
the ACC club readership initially, and are now Public Domain DOCs distributed
as part of the ACC club material by Mark). All DOC files appearing on the ACC
Club discs are in compressed format, and you'll need the packer/depacker that
is supplied with the ACC discs to be able to edit them, if this is your wish.
Should anyone out there have information to add to the files, please
contact either Mark or myself at the addresses above, sending your info as an
uncompressed ASCII file. I shall add the info to the relevant file when time
allows, and send off the latest version upon request. All contributors will
be acknowledged gratefully.
**** VERY IMPORTANT ****
Since the DOC files have now grown alarmingly in number (and size-they occupy
nearly 3MB when decompressed!) from 1/10/91 onwards, ALL requests to me for a
copy of the DOC DISC should be accompanied by TWO blank discs for each set of
DOC DISCS required. So, if three sets of DOC DISCS are required, the reader
should now send SIX blank discs, for example. Until I can arrange with Mark
to have the latest updates sent to him, please send ALL requests for DOC DISC
copies directly to me until some time in December 1991 (by which time the ACC
should have the latest updates via Mark). To give the reader some idea of the
monumental size of the DOCS, the files occupy 900K AFTER compression, and at
the time of typing occupy 2,787,490 bytes when unpacked! So, this should tie
your reading time up for the next three years...
UPDATE : typed_hardware_disc.doc current as of 14/2/92
Contributors : Dave Edwards
Mark Meany (ACC 17)
Vandal of Killers (Snippets, ACC 17)
Mark Flemans (ACC 18, movetrack00.s &
tcode.s